/* 
 * File:   BulletWrapper.cpp
 * Author: ja1e09
 * 
 * Created on August 15, 2011, 6:06 PM
 */

#include "BulletWrapper.h"

BulletWrapper* BulletWrapper::pInstance = 0;

BulletWrapper::BulletWrapper(void)
{

}

BulletWrapper* BulletWrapper::GetInstance(void)
{
    if (pInstance == 0)
        pInstance = new BulletWrapper;

    return pInstance;
}

void BulletWrapper::Destroy(void)
{
    if (pInstance != 0)
    {
        SAFE_DELETE(pInstance);
    }
}

void BulletWrapper::InitPhysics()
{
    ///collision configuration contains default setup for memory, collision setup. 
    ///Advanced users can create their own configuration.
    pCollisionConfiguration = new btDefaultCollisionConfiguration();

    ///use the default collision dispatcher. 
    ///For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
    pDispatcher = new btCollisionDispatcher(pCollisionConfiguration);

    ///btDbvtBroadphase is a good general purpose broadphase. You can also try out btAxis3Sweep.
    pOverlappingPairCache = new btDbvtBroadphase();

    ///the default constraint solver. 
    ///For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
    pSolver = new btSequentialImpulseConstraintSolver;

    pDynamicsWorld = new btDiscreteDynamicsWorld(pDispatcher, pOverlappingPairCache, pSolver, pCollisionConfiguration);

    pDynamicsWorld->setGravity(btVector3(0, -10, 0));
}

void BulletWrapper::EndPhysics()
{
    //delete dynamics world
    SAFE_DELETE(pDynamicsWorld);

    //delete solver
    SAFE_DELETE(pSolver);

    //delete broadphase
    SAFE_DELETE(pOverlappingPairCache);

    //delete dispatcher
    SAFE_DELETE(pDispatcher);

    SAFE_DELETE(pCollisionConfiguration);
}

void BulletWrapper::ReleasePhysics()
{
    //Remove the rigid bodies from the dynamics world and delete them
    for (register int i = pDynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
    {
        btCollisionObject* pCollisionObject = pDynamicsWorld->getCollisionObjectArray()[i];
        btRigidBody* pRigidBody = btRigidBody::upcast(pCollisionObject);
        if (pRigidBody && pRigidBody->getMotionState())
                delete pRigidBody->getMotionState();
        
        pDynamicsWorld->removeCollisionObject(pCollisionObject);
        SAFE_DELETE(pCollisionObject);
    }

    //Delete collision shapes
    //for (register unsigned int j = 0; j < collisionShapes.size(); j++)
    //{
    //    btCollisionShape* shape = collisionShapes[j];
    //    collisionShapes[j] = 0;
    //    delete shape;
    //}
}